home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / prg_casm / snip9611.zip / MCB_ENV.C < prev    next >
C/C++ Source or Header  |  1996-11-24  |  5KB  |  171 lines

  1. /* +++Date last modified: 28-Sep-1996 */
  2.  
  3. #include <stdio.h>
  4. #include <dos.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7.  
  8. #if defined(__TURBOC__) || defined(__POWERC) || defined(__ZTC__)
  9.  #if defined(__ZTC__)
  10.   #include <dos.h>
  11.  #else
  12.   #include <alloc.h>
  13.  #endif
  14. #else                                           /* MSC, Watcom    */
  15.  #include <malloc.h>
  16. #endif
  17.  
  18. #include "extkword.h"
  19. #include "mk_fp.h"
  20.  
  21. struct EnvRec {
  22.               unsigned EnvSeg;  /*Segment of the environment*/
  23.               unsigned EnvLen;  /*Usable length of the environment*/
  24.               } EnvRec;
  25.  
  26. struct EnvRec *MasterEnv(void)
  27. {
  28.       unsigned owner;
  29.       unsigned mcb;
  30.       unsigned eseg;
  31.       static struct EnvRec env;
  32.  
  33.       env.EnvSeg = env.EnvLen = 0;
  34.       owner = * ((unsigned FAR *) MK_FP(0, (2+4*0x2e)));
  35.  
  36.       /* int 0x2e points to command.com */
  37.  
  38.       mcb = owner -1;
  39.  
  40.       /*Mcb points to memory control block for COMMAND */
  41.  
  42.       if ( (*((char FAR *) MK_FP(mcb, 0)) != 'M') &&
  43.            (*((unsigned FAR *) MK_FP(mcb, 1)) != owner) )
  44.                  return (struct EnvRec *) 0;
  45.  
  46.       eseg = *((unsigned FAR *) MK_FP(owner, 0x2c));
  47.  
  48.       /* Read segment of environment from PSP of COMMAND} */
  49.       /* Earlier versions of DOS don't store environment segment there */
  50.  
  51.       if ( !eseg )
  52.       {
  53.  
  54.             /* Master environment is next block past COMMAND */
  55.  
  56.             mcb = owner + *((unsigned FAR *) MK_FP(mcb, 3));
  57.             if ( (*((char FAR *) MK_FP(mcb, 0)) != 'M') &&
  58.                  (*((unsigned FAR *) MK_FP(mcb, 1)) != owner) )
  59.                        return (struct EnvRec *) 0;
  60.             eseg = mcb + 1;
  61.       }
  62.       else  mcb = eseg-1;
  63.  
  64.       /* Return segment and length of environment */
  65.  
  66.       env.EnvSeg = eseg;
  67.       env.EnvLen = *((unsigned FAR *) MK_FP(mcb, 3)) << 4 ;
  68.       return &env;
  69. }
  70.  
  71. /*
  72. ** Then a function to find the string to be replaced.   This one'll
  73. ** return a pointer to the string, or a pointer to the first (of 2)
  74. ** NUL byte at the end of the environment.
  75. */
  76.  
  77. char FAR *SearchEnv( char FAR *eptr, char *search )
  78. {
  79.       char FAR *e;
  80.       char *s;
  81.       while ( *eptr )
  82.       {
  83.             for ( s=search, e=eptr; *e && *s && (*e == *s); e++, s++ )
  84.                   ;  /* NULL STATEMENT */
  85.             if ( !*s )
  86.                   break;
  87.             while ( *eptr )
  88.                   eptr++;           /* position to the NUL byte */
  89.             eptr++;                      /* next string */
  90.       }
  91.       return eptr;
  92. }
  93.  
  94. /*
  95. ** Now, the function to replace, add or delete.  If a value is not
  96. ** given, the string is deleted.
  97. */
  98.  
  99. int SetEnvStr( struct EnvRec *env, char *search, char *value )
  100. {
  101.       /* -Set environment string, returning true if successful */
  102.  
  103.       char FAR *envptr;
  104.       register char FAR *p;
  105.       char *s;
  106.       int newlen;
  107.       int oldlen;
  108.       int i;
  109.  
  110.       if ( !env->EnvSeg || !search )
  111.             return 0;
  112.  
  113.       /* get some memory for complete environment string */
  114.  
  115.       newlen = strlen(search) + sizeof((char) '\0') + strlen(value) + 2;
  116.       if ( (s = (char *) malloc( newlen)) == NULL )
  117.             return 0;
  118.       for ( i = 0; *search; search++, i++ )
  119.             s[i] = *search;
  120.       s[i++] = '=';
  121.       s[i] = '\0';
  122.       envptr = SearchEnv((char FAR *) MK_FP(env->EnvSeg, 0), s );
  123.       if ( *envptr )
  124.       {
  125.             for ( p = envptr, oldlen = 0; *p; oldlen++, p++ )
  126.                   ;     /* can't use strlen() because of far pointer */
  127.       }                 /* will set p to point to terminating NUL */
  128.  
  129.       if ( *value && (newlen > (int)env->EnvLen) ) /* not a deletion */
  130.       {
  131.             free( s );
  132.             return 0;                           /* won't fit */
  133.       }
  134.  
  135.       if ( *envptr )                            /* shift it down */
  136.       {
  137.             for ( ++p; (*p || *(p+1)); envptr++, p++ )
  138.                   *envptr = *p;
  139.             *envptr++ = '\0';
  140.             *envptr = '\0';
  141.       }
  142.       if ( *value )                             /* append it */
  143.       {
  144.             strcat(s, value);
  145.             while ( *s )
  146.                   *(envptr++) = *s++;
  147.             *envptr++ = '\0';
  148.             *envptr = '\0';
  149.       }
  150.       free(s);
  151.       return 1;
  152. }
  153.  
  154. /*
  155. ** Ok, just to show you that I tested it :
  156. */
  157.  
  158. main()
  159. {
  160.       char vn[80];
  161.       char va[80];
  162.       struct EnvRec *p = MasterEnv();
  163.  
  164.       puts("enter variable name:");
  165.       gets(vn);
  166.       puts("enter value:");
  167.       gets(va);
  168.       printf("SetEnvStr returned %d\n", SetEnvStr( p, strupr(vn), va) );
  169.       return 0;
  170. }
  171.